home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / C Internet Config / Examples ƒ / Example / IC Resource ƒ / Syslog Component ƒ / syslog component.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-15  |  20.3 KB  |  788 lines  |  [TEXT/SPM ]

  1. /*
  2.     Component.c
  3.     
  4.     Sample code for a simple component.  It really does nothing, but it can be used as a spring-board
  5.     for building other components.
  6. */
  7.  
  8. #if defined(powerc) || defined(__powerc)
  9. #include <stdlib.h>
  10. #endif
  11.  
  12. #include <Components.h>
  13. #include <Errors.h>
  14. #include <Packages.h>
  15. #include <Folders.h>
  16. #include <Notification.h>
  17.  
  18. #include "syslog internals.h"
  19. #include "syslog component.h"
  20.  
  21. #include "ShowInitIcon.h"
  22. #include "libsprintf.h"
  23.  
  24. /*
  25.     kIconID is the constant specifying which icon to display at system startup.  This allows for different
  26.     icons to be displayed depending on the code which is executing.
  27. */
  28. #if defined(powerc) || defined (__powerc)
  29. #define kIconID    140
  30. #else
  31. #define kIconID    141
  32. #endif
  33.  
  34. /*
  35.     kMaxIdentLen is a constant which represents the maximum size an ident string will be.  The total
  36.     max is 100.  By controling the size of the ident string, we ensure that there will be enough room in
  37.     a Str255 string for the ident string, time and date, priority, and message.
  38. */
  39. #define kMaxIdentLen 60
  40.  
  41. /*
  42.     kSyslogCreator is the creator type used when creating log files.  Use your favorite text editor here.
  43. */
  44. #define kSyslogCreator 'SPM '
  45.  
  46. pascal ComponentResult ComponentOpen(Handle storage,ComponentInstance self);
  47. pascal ComponentResult ComponentClose(Handle storage,ComponentInstance self);
  48. pascal ComponentResult ComponentCanDo(short selector);
  49. pascal ComponentResult ComponentVersion(void);
  50. pascal ComponentResult ComponentTarget(Handle storage,ComponentInstance self);
  51.  
  52. pascal ComponentResult ComponentRegister(Handle storage);
  53.  
  54. pascal ComponentResult ComponentOpenlog(Handle storage,const char* ident,long logopt,short facility);
  55. pascal ComponentResult ComponentSyslog(Handle storage,short priority,const char* message);
  56. pascal ComponentResult ComponentCloselog(Handle storage);
  57. pascal ComponentResult ComponentSetlogmask(Handle storage,short maskpri);
  58. pascal ComponentResult ComponentSetFile(Handle storage,FSSpecPtr spec);
  59.  
  60. pascal ComponentResult ComponentGetError(Handle storage,OSErr* err);
  61.  
  62. // some string routines so we don't need to include ANSI libs
  63. static short Strlen(char* s){
  64.     register char* cp=s;
  65.     register short sh=0;
  66.     
  67.     if (s==(char*)0)
  68.         return 0;
  69.     
  70.     while (*cp){
  71.         sh++;
  72.         cp++;
  73.     }
  74.     
  75.     return sh;
  76. }
  77.  
  78. static void Strncpy(char* s1,char* s2,short num){
  79.     
  80.     // copy the strings
  81.     BlockMoveData((Ptr)s2,(Ptr)s1,num);
  82.     
  83.     // terminate the new string
  84.     s1[num]=0;
  85. }
  86.  
  87. static void Strcpy(char* s1,char* s2){
  88.     // Call strncpy with the string's length
  89.     Strncpy(s1,s2,Strlen(s2));
  90. }
  91.  
  92. static void ConcatPString(StringPtr a,StringPtr b);
  93. static void ConcatPString(StringPtr a,StringPtr b){
  94.     register unsigned char* ap;
  95.     register unsigned char* bp;
  96.     register unsigned char c;
  97.     
  98.     ap=&(a[a[0]+1]);
  99.     bp=b;bp++;
  100.     c=b[0];
  101.     
  102.     while (c){
  103.         *ap=*bp;
  104.         ap++;
  105.         bp++;
  106.         c--;
  107.     }
  108.     
  109.     (a[0])+=b[0];
  110. }
  111.     
  112. pascal ComponentResult main(ComponentParameters* params,Handle storage){
  113.     ComponentResult res=((ComponentResult)noErr);
  114.     long lval;
  115.     ComponentFunctionUPP cfupp;
  116.     
  117. #if defined(powerc) || defined(__powerc)
  118.     __rsrcinit();
  119. #endif
  120.     
  121.     switch(params->what){
  122.         // Component Manager Routines
  123.         case kComponentOpenSelect:
  124.             cfupp=(ComponentFunctionUPP)NewComponentWithStorageProc(ComponentOpen);
  125.             res=CallComponentFunctionWithStorage(storage,params,cfupp);
  126.             DisposeComponentWithStorageProc(cfupp);
  127.             break;
  128.         case kComponentCloseSelect:
  129.             cfupp=(ComponentFunctionUPP)NewComponentWithStorageProc(ComponentClose);
  130.             res=CallComponentFunctionWithStorage(storage,params,cfupp);
  131.             DisposeComponentWithStorageProc(cfupp);
  132.             break;
  133.         case kComponentCanDoSelect:
  134.             cfupp=(ComponentFunctionUPP)NewComponentShortProc(ComponentCanDo);
  135.             res=CallComponentFunction(params,cfupp);
  136.             DisposeComponentShortProc(cfupp);
  137.             break;
  138.         case kComponentVersionSelect:
  139.             cfupp=(ComponentFunctionUPP)NewComponentVoidProc(ComponentVersion);
  140.             res=CallComponentFunction(params,cfupp);
  141.             DisposeComponentVoidProc(cfupp);
  142.             break;
  143.         case kComponentTargetSelect:
  144.             cfupp=(ComponentFunctionUPP)NewComponentWithStorageProc(ComponentTarget);
  145.             res=CallComponentFunctionWithStorage(storage,params,cfupp);
  146.             DisposeComponentWithStorageProc(cfupp);
  147.             break;
  148.         case kComponentRegisterSelect:
  149.             cfupp=(ComponentFunctionUPP)NewComponentHandleProc(ComponentRegister);
  150.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  151.             DisposeComponentHandleProc(cfupp);
  152.             res=(ComponentResult)lval;
  153.             break;
  154.         
  155.         // Component Specific Routines
  156.             
  157.         case kopenlogSelector:
  158.             cfupp=(ComponentFunctionUPP)NewComponentOpenlogProc(ComponentOpenlog);
  159.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  160.             DisposeComponentOpenlogProc(cfupp);
  161.             res=(ComponentResult)lval;
  162.             break;
  163.         case ksyslogSelector:
  164.             cfupp=(ComponentFunctionUPP)NewComponentSyslogProc(ComponentSyslog);
  165.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  166.             DisposeComponentSyslogProc(cfupp);
  167.             res=(ComponentResult)lval;
  168.             break;
  169.         case kcloselogSelector:
  170.             cfupp=(ComponentFunctionUPP)NewComponentHandleProc(ComponentCloselog);
  171.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  172.             DisposeComponentHandleProc(cfupp);
  173.             res=(ComponentResult)lval;
  174.             break;
  175.         case ksetlogmaskSelector:
  176.             cfupp=(ComponentFunctionUPP)NewComponentSetlogmaskProc(ComponentSetlogmask);
  177.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  178.             DisposeComponentSetlogmaskProc(cfupp);
  179.             res=(ComponentResult)lval;
  180.             break;
  181.         case kSetFileSelector:
  182.             cfupp=(ComponentFunctionUPP)NewComponentSetFileProc(ComponentSetFile);
  183.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  184.             DisposeComponentSetFileProc(cfupp);
  185.             res=(ComponentResult)lval;
  186.             break;
  187.         case kGetErrorSelector:
  188.             cfupp=(ComponentFunctionUPP)NewComponentOSErrPtrProc(ComponentGetError);
  189.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  190.             DisposeComponentOSErrPtrProc(cfupp);
  191.             res=(ComponentResult)lval;
  192.             break;
  193.         
  194.         default:
  195.             res=badComponentSelector;
  196.             break;
  197.     }
  198.     
  199. #if defined(powerc) || defined(__powerc)
  200.     __rsrcterm();
  201. #endif
  202.     
  203.     return res;
  204. }
  205.  
  206. pascal ComponentResult ComponentOpen(Handle storage,ComponentInstance self){
  207.     ComponentStorageHdl sto;
  208.     ComponentResult res=((ComponentResult)noErr);
  209.     OSErr anErr=noErr;
  210.     short vref;
  211.     long dirid;
  212.     Handle i0h;
  213.     
  214.     sto=(ComponentStorageHdl)NewHandleClear(sizeof(ComponentStorageRec));
  215.     
  216.     if (sto==(ComponentStorageHdl)0){
  217.         res=((ComponentResult)MemError());
  218.     } else {
  219.         
  220.         HLock((Handle)sto);
  221.         
  222.         // (*sto)->resFileRefNum=OpenComponentResFile((Component)self); // open the resource file
  223.         
  224.         (*sto)->self=(Component)self;
  225.         
  226.         // create default values for the syslog stuff
  227.         (*sto)->ident[0]=0;
  228.         (*sto)->refnum=0;
  229.         (*sto)->logopts=0; // really ignored
  230.         (*sto)->facility=LOG_USER; // random user messages
  231.         (*sto)->mask=0xff; // mask nothing away
  232.         (*sto)->specvalid=false;
  233.         (*sto)->err=noErr;
  234.         
  235.         (*sto)->openCalled=false;
  236.         (*sto)->slogopts=(*sto)->logopts;
  237.         (*sto)->sfacility=(*sto)->facility;
  238.         (*sto)->smask=(*sto)->mask;
  239.         (*sto)->needSaved=false;
  240.         
  241.         // Set up the IU stuff
  242.         (*sto)->i0h=(Intl0Hndl)IUGetIntl(0);
  243.         
  244.         if ((*sto)->i0h!=(Intl0Hndl)0){
  245.             // detach it so we don't save the changes...
  246.             DetachResource((Handle)(*sto)->i0h);
  247.             
  248.             // date as 01/01/95
  249.             (*((*sto)->i0h))->shrtDateFmt|=dayLdingZ;
  250.             (*((*sto)->i0h))->shrtDateFmt&=~century;
  251.             
  252.             // time as 15:06:30
  253.             (*((*sto)->i0h))->timeCycle=0;
  254.             (*((*sto)->i0h))->timeFmt|=secLeadingZ|minLeadingZ|hrLeadingZ;
  255.         }
  256.         
  257.         /*
  258.             Start with the default syslog spec.  A file named 'syslog' will be created in the
  259.             system folder.  Use SetFile to change the spec to point somewhere else...
  260.         */
  261.         anErr=FindFolder(kOnSystemDisk,kSystemFolderType,kCreateFolder,&vref,&dirid);
  262.         if (anErr==noErr){
  263.             FInfo info;
  264.             
  265.             (*sto)->vRefNum=0;
  266.             (*sto)->dirID=0L;
  267.             
  268.             anErr=FSMakeFSSpec(vref,dirid,"\psyslog",&((*sto)->spec));
  269.             
  270.             // (*sto)->spec.vRefNum=vref;
  271.             // (*sto)->spec.parID=dirid;
  272.             
  273.             if ((anErr==noErr)||(anErr==fnfErr)){
  274.                 (*sto)->specvalid=true;
  275.                 
  276.                 (*sto)->vRefNum=vref;
  277.                 (*sto)->dirID=dirid;
  278.                 
  279.                 anErr=noErr;
  280.             }
  281.         }
  282.         
  283.         (*sto)->err=anErr;
  284.         
  285.         HUnlock((Handle)sto);
  286.         
  287.         SetComponentInstanceStorage(self,(Handle)sto);
  288.     }
  289.     
  290.     return res;
  291. }
  292.  
  293. pascal ComponentResult ComponentClose(Handle storage,ComponentInstance self){
  294.     ComponentResult res=((ComponentResult)noErr);
  295.     SignedByte s=HGetState(storage);
  296.     ComponentStorageHdl sto;
  297.     
  298.     HLock(storage);
  299.     sto=(ComponentStorageHdl)storage;
  300.     
  301.     DisposeHandle((Handle)(*sto)->i0h);
  302.     
  303.     HSetState(storage,s);
  304.     
  305.     DisposeHandle(storage);
  306.     
  307.     return res;
  308. }
  309.  
  310. pascal ComponentResult ComponentCanDo(short selector){
  311.     ComponentResult res=((ComponentResult)noErr);
  312.     
  313.     switch(selector){
  314.         // Component Manager Routines
  315.         case kComponentOpenSelect:
  316.         case kComponentCloseSelect:
  317.         case kComponentCanDoSelect:
  318.         case kComponentVersionSelect:
  319.         case kComponentTargetSelect:
  320.         case kComponentRegisterSelect:
  321.         
  322.         // Add component specific routines here...
  323.         case kopenlogSelector:
  324.         case ksyslogSelector:
  325.         case kcloselogSelector:
  326.         case ksetlogmaskSelector:
  327.         case kSetFileSelector:
  328.         case kGetErrorSelector:
  329.         
  330.             res=((ComponentResult)1);
  331.             break;
  332.         default:
  333.             res=((ComponentResult)0);
  334.             break;
  335.     }
  336.     
  337.     return res;
  338. }
  339.  
  340. pascal ComponentResult ComponentVersion(void){
  341.     ComponentResult res=((ComponentResult)kVersion);
  342.     
  343.     return res;
  344. }
  345.  
  346. pascal ComponentResult ComponentTarget(Handle storage,ComponentInstance kidnapper){
  347.     ComponentResult res=((ComponentResult)noErr);
  348.     SignedByte s=HGetState(storage);
  349.     ComponentStorageHdl sto;
  350.     
  351.     HLock(storage);
  352.     sto=(ComponentStorageHdl)storage;
  353.     
  354.     (*sto)->kidnapper=kidnapper;
  355.     
  356.     HSetState(storage,s);
  357.     
  358.     return res;
  359. }
  360.  
  361. pascal ComponentResult ComponentRegister(Handle storage){
  362.     ComponentResult res=((ComponentResult)noErr);
  363.     short refnum,oldref;
  364.     SignedByte s=HGetState(storage);
  365.     ComponentStorageHdl sto;
  366.     
  367.     HLock(storage);
  368.     sto=(ComponentStorageHdl)storage;
  369.     
  370.     oldref=CurResFile();
  371.     
  372.     refnum=OpenComponentResFile((*sto)->self);
  373.     
  374.     if (refnum>0){
  375.         // use our resource file
  376.         UseResFile(refnum);
  377.         
  378.         // show the icon
  379.         ShowInitIcon(kIconID,true);
  380.         
  381.         // close our resource file
  382.         CloseComponentResFile(refnum);
  383.         
  384.         // restore the old front resource
  385.         UseResFile(oldref);
  386.     } else {
  387.         (*sto)->err=2005;
  388.     }
  389.     
  390.     HSetState(storage,s);
  391.     
  392.     return res;
  393. }
  394.  
  395. // Add component specific routines here or in another file
  396.  
  397. /*
  398.     ComponentOpenlog
  399.     
  400.     Handles the opening of the syslog file.  Note that if we are opening an existing file, it's contents are
  401.     purged.
  402. */
  403. pascal ComponentResult ComponentOpenlog(Handle storage,const char* ident,long logopt,short facility){
  404.     ComponentResult res;
  405.     SignedByte s=HGetState(storage);
  406.     ComponentStorageHdl sto;
  407.     
  408.     HLock(storage);
  409.     sto=(ComponentStorageHdl)storage;
  410.     
  411.     // save the current stuff if necessary
  412.     if (!((*sto)->openCalled)){
  413.         // open called for the first time...
  414.         if ((*sto)->needSaved){
  415.             // the settings have changed, so we are not just resetting the syslog file
  416.             (*sto)->openCalled=true;
  417.             (*sto)->slogopts=(*sto)->logopts;
  418.             (*sto)->sfacility=(*sto)->facility;
  419.             (*sto)->smask=(*sto)->mask;
  420.         }
  421.     }
  422.     
  423.     if (Strlen((char*)ident)){
  424.         // save the current ident string
  425.         if (Strlen((char*)ident)>kMaxIdentLen){
  426.             Strncpy((*sto)->ident,(char*)ident,kMaxIdentLen);
  427.         } else {
  428.             Strcpy((*sto)->ident,(char*)ident);
  429.         }
  430.     } else {
  431.         (*sto)->ident[0]=0;
  432.     }
  433.     
  434.     // save the logopts
  435.     (*sto)->logopts=logopt;
  436.     
  437.     // save the facility
  438.     if ((facility!=0)&&((facility&~LOG_FACMASK)==0))
  439.         (*sto)->facility=facility;
  440.     
  441.     // purge the existing file if it exists
  442.     if ((*sto)->specvalid){
  443.         FInfo info;
  444.         
  445.         res=FSpGetFInfo(&((*sto)->spec),&info);
  446.         
  447.         if (res==noErr){
  448.             // the file exists, get rid of it
  449.             res=FSpDelete(&((*sto)->spec));
  450.             
  451.             if (res!=noErr){
  452.                 // file is busy or something, move it to the trash folder
  453.                 long dirid;
  454.                 short vref;
  455.                 FSSpec trash;
  456.                 
  457.                 // find the trash folder
  458.                 FindFolder(kOnSystemDisk,kTrashFolderType,kCreateFolder,&vref,&dirid);
  459.                 
  460.                 // make a spec for it
  461.                 FSMakeFSSpec(vref,dirid,(*sto)->spec.name,&trash);
  462.                 
  463.                 // allow the move to happen
  464.                 FSpCatMove(&((*sto)->spec),&trash);
  465.             }
  466.         }
  467.     }
  468.     
  469.     (*sto)->err=(OSErr)res;
  470.     
  471.     HSetState(storage,s);
  472.     
  473.     return res;
  474. }
  475.  
  476. pascal ComponentResult ComponentSyslog(Handle storage,short priority,const char* message){
  477.     ComponentResult res=noErr;
  478.     SignedByte s=HGetState(storage);
  479.     ComponentStorageHdl sto;
  480.     Str255 msg;
  481.     Str255 nstr;
  482.     long ct;
  483.     unsigned long time;
  484.     OSErr anErr=noErr;
  485.     char tempBuf[200];
  486.     
  487.     if (priority&~(LOG_PRIMASK|LOG_FACMASK)){
  488.         libsprintf(tempBuf,"syslog: unknown facility/priority: %x",priority);
  489.         ComponentSyslog(storage,LOG_ERR,tempBuf);
  490.         
  491.         priority&=LOG_PRIMASK|LOG_FACMASK;
  492.     }
  493.     
  494.     HLock(storage);
  495.     sto=(ComponentStorageHdl)storage;
  496.     
  497.     // if the priority clears the mask...  Basically if the bit in the mask is set for this priority,
  498.     // then we can continue (i.e. logging or notifying).
  499.     if ( (!LOG_MASK(LOG_PRI(priority))) & ((*sto)->mask) ){
  500.         anErr=noErr;
  501.         goto ExitSyslog;
  502.     }
  503.     
  504.     if ((priority&LOG_FACMASK)==0){
  505.         // use the default facility
  506.         priority|=(*sto)->facility;
  507.     }
  508.     
  509.     nstr[0]=0;
  510.     
  511.     switch (priority&LOG_PRIMASK){
  512.         case LOG_EMERG:
  513.             ConcatPString(nstr,"\p<Emergency> ");
  514.             break;
  515.         case LOG_ALERT:
  516.             ConcatPString(nstr,"\p<Alert> ");
  517.             break;
  518.         case LOG_CRIT:
  519.             ConcatPString(nstr,"\p<Critical> ");
  520.             break;
  521.         case LOG_ERR:
  522.             ConcatPString(nstr,"\p<Error> ");
  523.             break;
  524.         case LOG_WARNING:
  525.             ConcatPString(nstr,"\p<Warning> ");
  526.             break;
  527.         case LOG_INFO:
  528.             ConcatPString(nstr,"\p<Info> ");
  529.             break;
  530.         case LOG_DEBUG:
  531.             ConcatPString(nstr,"\p<Debug> ");
  532.             break;
  533.         case LOG_NOTICE:
  534.             ConcatPString(nstr,"\p<Notice> ");
  535.             break;
  536.         default:
  537.             {
  538.                 // priority not in range, encode the number as a priority
  539.                 Str255 tstr;
  540.                 NumToString(priority,tstr);
  541.                 
  542.                 ConcatPString(nstr,"\p<");
  543.                 ConcatPString(nstr,tstr);
  544.                 ConcatPString(nstr,"\p> ");
  545.             }
  546.             break;
  547.     }
  548.     
  549.     ReadDateTime(&time); // get time
  550.     
  551.     // build the date string
  552.     IUDatePString(time,shortDate,msg,(Handle)(*sto)->i0h);
  553.     
  554.     // add it to the nstr
  555.     ConcatPString(nstr,msg);
  556.     ConcatPString(nstr,"\p ");
  557.     
  558.     // build the time string
  559.     IUTimePString(time,true,msg,(Handle)(*sto)->i0h);
  560.     
  561.     // add it to the nstr
  562.     ConcatPString(nstr,msg);
  563.     ConcatPString(nstr,"\p ");
  564.     
  565.     // add the ident
  566.     ct=Strlen((*sto)->ident);
  567.     if (ct>0){
  568.         BlockMoveData((*sto)->ident,&(nstr[nstr[0]+1]),ct);
  569.         nstr[0]+=ct;
  570.         ConcatPString(nstr,"\p ");
  571.     } else {
  572.         // use syslog:
  573.         ConcatPString(nstr,"\psyslog");
  574.     }
  575.     
  576.     // add the ': '
  577.     ConcatPString(nstr,"\p: ");
  578.     
  579.     /*
  580.         In normal syslog implementations, a connection is opened with the syslog daemon
  581.         and the string is passed to the syslog daemon for logging (and the console if the flag is
  582.         set).  The connection is usually an AF_UNIX connection, or local system connection.
  583.         
  584.         In this component, we open a file, add the message, then close the file.  Close enough to
  585.         a local system connection for me ;-)
  586.         
  587.         Barring any crashes while the file is open, this will ensure that the file is updated and
  588.         closed so no messages are lost.
  589.         
  590.         This also means that when I write a syslog daemon that I can have the daemon open a file
  591.         and write this information into it just as easily.
  592.     */
  593.     
  594.     // add the message to the log file
  595.     if ((*sto)->specvalid){
  596.         // open the file
  597.         anErr=FSpOpenDF(&((*sto)->spec),fsRdWrPerm,&((*sto)->refnum));
  598.         
  599.         // move to the end of the file if it's open
  600.         if (anErr==noErr)
  601.             SetFPos((*sto)->refnum,fsFromLEOF,0L);
  602.         else {
  603.             (*sto)->refnum=0;
  604.             
  605.             // problem opening the file, try to create it...
  606.             anErr=FSpCreate(&((*sto)->spec),kSyslogCreator,'TEXT',smSystemScript);
  607.             
  608.             if (anErr==noErr){
  609.                 // if the file was just created, then we don't need to seek, just open
  610.                 anErr=FSpOpenDF(&((*sto)->spec),fsRdWrPerm,&((*sto)->refnum));
  611.                 if (anErr!=noErr)
  612.                     (*sto)->refnum=0;
  613.             } else {
  614.                 // DebugNotify("\pLog component: Error creating the file!");
  615.             }
  616.         }
  617.         
  618.         if ((anErr==noErr)&&((*sto)->refnum!=0)){
  619.             // OK to write to the file, add the nstr first
  620.             ct=(long)(nstr[0]);
  621.             FSWrite((*sto)->refnum,&ct,&(nstr[1]));
  622.             
  623.             // add the message to the file
  624.             ct=(long)Strlen((char*)message);
  625.             FSWrite((*sto)->refnum,&ct,message);
  626.             
  627.             // now add a newline char
  628.             msg[1]=0x0d;
  629.             ct=1;
  630.             FSWrite((*sto)->refnum,&ct,&(msg[1]));
  631.             
  632.             // done, flush & close file
  633.             FSClose((*sto)->refnum);
  634.             (*sto)->refnum=0;
  635.             FlushVol((StringPtr)0,(*sto)->spec.vRefNum);
  636.         }
  637.     } else {
  638.         anErr=2002; // fsspec is invalid
  639.     }
  640.     
  641. ExitSyslog:
  642.     (*sto)->err=anErr;
  643.     
  644.     HSetState(storage,s);
  645.     
  646.     return res;
  647. }
  648.  
  649. pascal ComponentResult ComponentCloselog(Handle storage){
  650.     ComponentResult res=noErr;
  651.     SignedByte s=HGetState(storage);
  652.     ComponentStorageHdl sto;
  653.     
  654.     HLock(storage);
  655.     sto=(ComponentStorageHdl)storage;
  656.     
  657.     // the current log should be closed and the old syslog reused.
  658.     
  659.     if ((*sto)->openCalled){
  660.         // open was called and the settings were changed
  661.         // restore the settings to the default values.
  662.         
  663.         (*sto)->openCalled=false;
  664.         (*sto)->facility=(*sto)->sfacility;
  665.         (*sto)->mask=(*sto)->smask;
  666.         (*sto)->logopts=(*sto)->slogopts;
  667.         (*sto)->needSaved=false;
  668.         (*sto)->ident[0]=0;
  669.         
  670.         if (((*sto)->vRefNum!=0)&&((*sto)->dirID!=0L)){
  671.             FSMakeFSSpec((*sto)->vRefNum,(*sto)->dirID,"\psyslog",&((*sto)->spec));
  672.             (*sto)->specvalid=true;
  673.         } else {
  674.             (*sto)->specvalid=false;
  675.         }
  676.     }
  677.     
  678.     HSetState(storage,s);
  679.     
  680.     return res;
  681. }
  682.  
  683. pascal ComponentResult ComponentSetlogmask(Handle storage,short maskpri){
  684.     ComponentResult res;
  685.     SignedByte s=HGetState(storage);
  686.     ComponentStorageHdl sto;
  687.     
  688.     HLock(storage);
  689.     sto=(ComponentStorageHdl)storage;
  690.     
  691.     res=(ComponentResult)(*sto)->mask;
  692.     
  693.     // save the new mask
  694.     if (maskpri!=0)
  695.         (*sto)->mask=maskpri;
  696.     (*sto)->needSaved=true;
  697.     
  698.     HSetState(storage,s);
  699.     
  700.     return res;
  701. }
  702.  
  703. pascal ComponentResult ComponentSetFile(Handle storage,FSSpecPtr spec){
  704.     ComponentResult res;
  705.     SignedByte s=HGetState(storage);
  706.     ComponentStorageHdl sto;
  707.     Boolean didClose=false;
  708.     
  709.     HLock(storage);
  710.     sto=(ComponentStorageHdl)storage;
  711.     
  712.     (*sto)->specvalid=false;
  713.     
  714.     // save the fsspec stuff
  715.     res=FSMakeFSSpec(spec->vRefNum,spec->parID,spec->name,&((*sto)->spec));
  716.     
  717.     if ((res==noErr)||(res==fnfErr)){
  718.         (*sto)->specvalid=true;
  719.         (*sto)->needSaved=true;
  720.     }
  721.     
  722.     HSetState(storage,s);
  723.     
  724.     return res;
  725. }
  726.  
  727. pascal ComponentResult ComponentGetError(Handle storage,OSErr* err){
  728.     ComponentResult res=noErr;
  729.     SignedByte s=HGetState(storage);
  730.     ComponentStorageHdl sto;
  731.     
  732.     HLock(storage);
  733.     sto=(ComponentStorageHdl)storage;
  734.     
  735.     *err=(*sto)->err;
  736.     (*sto)->err=noErr;
  737.     
  738.     HSetState(storage,s);
  739.     
  740.     return res;
  741. }
  742.  
  743. /*
  744.     In PPC applications, constructors and destructors for global and static objects are called automatically
  745.     by __cplusstart, which is actually the main entry point to your application (and not main()).  This
  746.     routine calls your constructors, initializes your QuickDraw globals, calls your main() function, then
  747.     calls your destructors.
  748.     
  749.     In a shared library, constructors for global and static objects are called by __cplusinit, which the linker
  750.     assigns as an initialization routine.  The Code Fragment Manager will automatically call this initialization
  751.     routine when your shared library is loaded.  __cplusinit will also allow hook your shared library's
  752.     QuickDraw globals to the QuickDraw globals of the calling application.  Destructors for global and static
  753.     objects are called by __cplusterm, which the linker assigns as a termination routine.  The Code Fragment
  754.     Manager will automatically call this termination routine when your shared library is unloaded.
  755.     
  756.     In code resources, there is no way to call these constructors or destructors automatically, or hook
  757.     QuickDraw globals, and still preserve the arguments passed to your main entry point (main()).  Instead,
  758.     you will need to call initialization and termination routines to do this for you.
  759.     
  760.     In C, you should use __rsrcinit() and __rsrcterm(), defined in stdlib.h.
  761.     
  762.     In C++, you should use __cplusrsrcinit() and __cplusrsrcterm(), defined in new.h.
  763.     
  764.     The C++ initialization and termination routines will automatically call the C initialization and termination
  765.     routines.  You should only use one set or the other.
  766.     
  767.     You must not use any objects that rely on their constructor, or any QuickDraw globals, before calling
  768.     __rsrcinit() or __cplusrsrcinit().
  769.     
  770.     
  771.     Singlely-entrant code resources :
  772.     
  773.     If your code resource is called only once, you should call __rsrcinit() or __cplusrsrcinit() at the start of
  774.     main(), and __rsrcterm() or __cplusrsrcterm() at the end.
  775.     
  776.     Reentrant code resources :
  777.     
  778.     If your code resource is reentrant, you will need to call __rsrcinit() or __cplusrsrcinit() only the first
  779.     time through, and __rsrcterm() or __cplusrsrcterm() the last time through.
  780.     
  781.     
  782.     Colen Garoutte-Carson
  783.     Symantec Corp.
  784. */
  785.  
  786.  
  787.  
  788.